package at.socialconference.web.client.ui;

import java.util.HashMap;
import java.util.List;

import at.socialconference.inter.model.Conference;
import at.socialconference.inter.model.Place;
import at.socialconference.inter.model.Talk;
import at.socialconference.inter.model.User;
import at.socialconference.web.client.SCwebService;
import at.socialconference.web.client.controller.ViewController;

import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;

public class Home extends VerticalPanel implements ChangeHandler {
	private Label lblHello;
	private HorizontalPanel conferenceBrowsePanel;
	private ConferenceListBox conferences;
	private TalkListBox talks;
	private FlexTable details;
	private Label talksTitel;
	private Label conferencesTitel;
	private Button enrollBtn;

	private class ConferenceListBox extends ListBox {
		private HashMap<Integer, Conference> mappedConferences = new HashMap<Integer, Conference>();

		public void addConference(Conference conference) {
			mappedConferences.put(conference.getId(), conference);
			addItem(conference.getName(), conference.getId().toString());
		}

		public Conference getSelectedConference() {
			Conference selectedConference = null;
			try {
				selectedConference = mappedConferences.get(Integer
						.parseInt(getValue(getSelectedIndex())));
			} catch (Exception e) {
			}
			return selectedConference;
		}
	}

	private class TalkListBox extends ListBox {
		private HashMap<Integer, Talk> mappedTalks = new HashMap<Integer, Talk>();

		public void addTalk(Talk talk) {
			mappedTalks.put(talk.getId(), talk);
			addItem(talk.getTitle(), talk.getId().toString());
		}

		public Talk getSelectedTalk() {
			Talk selectedTalk = null;
			try {
				selectedTalk = mappedTalks.get(Integer
						.parseInt(getValue(getSelectedIndex())));
			} catch (Exception e) {
			}
			return selectedTalk;
		}
	}

	private class AsyncCallbackGetConferences implements
	AsyncCallback<List<Conference>> {
		public void onFailure(Throwable caught) {
			Window.alert("Server unreachable");
		}

		public void onSuccess(List<Conference> result) {
			ConferenceListBox conferences = Home.this.conferences;
			conferences.clear();
			for (Conference c : result) {
				conferences.addConference(c);
			}
		}
	}

	public Home() {

		User user = ViewController.getInstance().getClientUser();

		lblHello = new Label("Hello Mr. " + user.getFirstname() + " "
				+ user.getLastname());
		add(lblHello);

		conferenceBrowsePanel = new HorizontalPanel();
		add(conferenceBrowsePanel);

		details = new FlexTable();
		add(details);

		details.getElement().getStyle().setPadding(20, Unit.PX);

		conferences = new ConferenceListBox();
		talks = new TalkListBox();

		conferencesTitel = new Label("Conferences");
		talksTitel = new Label("Talks");

		conferences.setTitle("Conferences");
		talks.setTitle("Talks");

		conferences.addItem("<No conferences currently>");
		talks.addItem("<Select a Conference to show its talks>");

		conferences.getElement().getStyle().setMargin(5, Unit.PX);
		talks.getElement().getStyle().setMargin(5, Unit.PX);

		conferences.setVisibleItemCount(15);
		talks.setVisibleItemCount(15);

		conferences.addChangeHandler(this);
		talks.addChangeHandler(this);

		conferences.setWidth("400px");
		talks.setWidth("400px");

		VerticalPanel confVP = new VerticalPanel();
		VerticalPanel talkVP = new VerticalPanel();

		confVP.add(conferencesTitel);
		confVP.add(conferences);

		talkVP.add(talksTitel);
		talkVP.add(talks);

		conferenceBrowsePanel.add(confVP);
		conferenceBrowsePanel.add(talkVP);

		SCwebService.Util.getInstance().getConferences(
				new AsyncCallbackGetConferences());
	}

	private void showDetails() {
		details.clear();
		int i=-1;
		Conference c = null;
		if (conferences.getSelectedConference()!=null) {
			c = conferences.getSelectedConference();
			final Place place = c.getPlace();
			details.setWidget(++i, 0, new Label("Conference:"));
			details.setWidget(i, 1, new Label(c.getName()));

			details.setWidget(++i, 0, new Label("Description:"));
			details.setWidget(i, 1, new Label(c.getDescription()));

			details.setWidget(++i, 0, new Label("Date:"));
			String from = DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT).format(c.getDate_from());
			String to = DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT).format(c.getDate_to());
			details.setWidget(i, 1, new Label(from + " - " + to));

			details.setWidget(++i, 0, new Label("Place:"));
			if(c.getPlace()!=null && c.getPlace().getLatitude()!=null&&
					c.getPlace().getLatitude()!=0.0&&c.getPlace().getLongitude()!=null&&c.getPlace().getLongitude()!=0.0){
				Button btn = new Button();
				btn.setText(c.getPlace().getName());
				btn.addClickHandler(new ClickHandler() {
					@Override
					public void onClick(ClickEvent event) {
						new MapPopUp(place);
					}
				});
				details.setWidget(i, 1, btn);
			}else{
				details.setWidget(i, 1, new Label(c.getPlace()!=null?c.getPlace().getName():""));
			}
			String code = "002bb00"+c.getId();

			details.setWidget(++i, 0, new Label("QRCode:"));
			Image img = new Image("QRCodeServlet?message="+code);
			img.setPixelSize(125, 125);
			details.setWidget(i, 1, img);

		}

		if (talks.getSelectedTalk()!=null) {
			final Talk t = talks.getSelectedTalk();

			details.setWidget(++i, 0, new Label("Talk:"));
			details.setWidget(i, 1, new Label(t.getTitle()));

			details.setWidget(++i, 0, new Label("Description:"));
			details.setWidget(i, 1, new Label(t.getDescription()));

			String date = DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT).format(t.getDate());
			String timeFrom = DateTimeFormat.getFormat(PredefinedFormat.TIME_SHORT).format(t.getFrom());
			String timeTo = DateTimeFormat.getFormat(PredefinedFormat.TIME_SHORT).format(t.getTo());

			details.setWidget(++i, 0, new Label("Date:"));
			details.setWidget(i, 1, new Label(date + " at " + timeFrom + " - " + timeTo));



			details.setWidget(++i, 0, new Label("Place:"));
			if(t.getPlace()!=null && t.getPlace().getLatitude()!=null&&
					t.getPlace().getLatitude()!=0.0&&t.getPlace().getLongitude()!=null&&t.getPlace().getLongitude()!=0.0){
				Button btn = new Button();
				btn.setText(t.getPlace().getName());
				btn.addClickHandler(new ClickHandler() {
					@Override
					public void onClick(ClickEvent event) {
						new MapPopUp(t.getPlace());
					}
				});
				details.setWidget(i, 1, btn);
			}else{
				details.setWidget(i, 1, new Label(t.getPlace()!=null?t.getPlace().getName():""));
			}


			String code = "003bb00"+t.getId();

			details.setWidget(++i, 0, new Label("QRCode:"));
			Image img = new Image("QRCodeServlet?message="+code);
			img.setPixelSize(125, 125);
			details.setWidget(i, 1, img);

			List<User> speakers = t.getSpeakers();

			if (speakers!=null && speakers.size()>0) {
				HorizontalPanel speakersPanel = new HorizontalPanel();
				for (User s : speakers) {
					speakersPanel.add(new LabelLinkedUser(s, false));
					speakersPanel.add(new Label(","));
				}
				//quickndirty
				speakersPanel.remove(speakersPanel.getWidgetCount()-1);

				details.setWidget(++i, 0, new Label("Speakers:"));
				details.setWidget(i, 1, speakersPanel);
			}
		}
		if(c!=null)
			SCwebService.Util.getInstance().isEnrolled(c.getId(), new AsyncCallBackIsEnrolled());
	}

	public void onChange(ChangeEvent event) {
		if (event == null)
			return;
		if (event.getSource().equals(conferences)) {
			if (conferences.getSelectedConference() == null)
				return;
			talks.clear();
			String title = "Talks at "
				+ conferences.getSelectedConference().getName();
			talks.setTitle(title);
			talksTitel.setText(title);
			List<Talk> conferenceTalks = conferences.getSelectedConference()
			.getTalks();

			for (Talk t : conferenceTalks) {
				talks.addTalk(t);
			}

			showDetails();
		} else if (event.getSource().equals(talks)) {
			if (conferences.getSelectedConference() == null)
				return;
			showDetails();
		}

	}

	private class AsyncCallBackIsEnrolled implements AsyncCallback<Boolean>{

		@Override
		public void onFailure(Throwable caught) {
			Window.alert("Server unreacheable");			
		}

		@Override
		public void onSuccess(Boolean result) {
			if(!result){
				enrollBtn = new Button();
				enrollBtn.setText("Enroll");

				enrollBtn.addClickHandler(new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						SCwebService.Util.getInstance().enroll(conferences.getSelectedConference().getId(), new ASyncCallBackEnroll());					
					}
				});

				details.setWidget(details.getRowCount(), 1, enrollBtn);
			}else{
				details.setWidget(details.getRowCount(), 1, new Label("You are Participant of this Conference"));
			}
		}
	}


	private class ASyncCallBackEnroll implements AsyncCallback<Integer>{

		@Override
		public void onFailure(Throwable caught) {
			Window.alert("Server unreacheable");
		}

		@Override
		public void onSuccess(Integer result) {
			if(result==1){
				enrollBtn.setVisible(false);
			}
		}

	}
}


